package com.bdqn.service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.bdqn.entity.OmsOrder;
import com.bdqn.entity.OmsOrderItem;
import com.bdqn.entity.allParams.PreSubmitParam;
import com.bdqn.entity.allParams.SkuInfos;
import com.bdqn.entity.responseDate.cart.OmsCartDto;
import com.bdqn.entity.responseDate.order.PreSubmitDto;
import com.bdqn.entity.responseDate.pmsProduct.PmsSkuDto;
import com.bdqn.entity.util.Constants;
import com.bdqn.entity.util.ResultEnum;
import com.bdqn.mapper.OmsOrderItemMapper;
import com.bdqn.mapper.OmsOrderMapper;
import com.bdqn.mapper.PmsSkuMapper;
import com.bdqn.service.OmsOrderService;
import com.bdqn.util.BaseException;
import com.bdqn.util.OrderDelayQueueConfig;
import com.bdqn.util.OrderUtil;
import com.bdqn.util.Pet_service_RedisTemplate;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.amqp.AmqpException;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.core.MessagePostProcessor;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;

/**
 * <p>
 * 订单表 服务实现类
 * </p>
 *
 * @author hunter
 * @since 2022-04-30
 */
@Service
public class OmsOrderServiceImpl extends ServiceImpl<OmsOrderMapper, OmsOrder> implements OmsOrderService {
    Logger logger = LoggerFactory.getLogger(OmsOrderServiceImpl.class);
    @Autowired
    private PmsSkuMapper pmsSkuMapper;
    @Autowired
    private OmsOrderMapper omsOrderMapper;
    @Autowired
    private OmsOrderItemMapper omsOrderItemMapper;
    @Autowired
    private Pet_service_RedisTemplate pet_service_redisTemplate;
    @Autowired
    private RabbitTemplate rabbitTemplate;
    /**
     * 获取预支付的信息  通过skuId 和num数量
     *
     * @param skuInfos
     * @return
     */
    @Override
    public PreSubmitDto preSubmitDto(SkuInfos[] skuInfos, Long userId) {
        Logger logger = LoggerFactory.getLogger(OmsOrderServiceImpl.class);
        //用来存放返回的所有数据信息
        PreSubmitDto preSubmitDto = new PreSubmitDto();
        //总价格
        BigDecimal totalMoney = new BigDecimal(0);
        //邮费
        BigDecimal freight = new BigDecimal(10);
        //循环获取每一个参数对象
        List<OmsCartDto> productList = new ArrayList<>();
        for (int i = 0; i < skuInfos.length; i++) {
            SkuInfos skuInfo = skuInfos[i];//每一个参数对象
            //通过skuId 进行联spu表查询出来信息并映射
            PmsSkuDto pmsSkuDto = pmsSkuMapper.pmsSkuDto(skuInfo.getSkuId());
            if (pmsSkuDto == null || !pmsSkuDto.getPublishStatus().equals(Constants.Spu.PUBLISH_STATUS_ON)) {
                logger.info("要购买的商品skuId:{}，不存在", skuInfo.getSkuId());
                throw new BaseException(ResultEnum.PRODUCT_SPU_EMPTY);
            }
            if (pmsSkuDto.getStock() < skuInfo.getSkuNum()) {
                logger.info("要购买的商品skuId:{}，库存不足,购买数量:{},当前库存：stock:{}"
                        , skuInfo.getSkuId(), skuInfo.getSkuNum(), pmsSkuDto.getStock());
                throw new BaseException(ResultEnum.ADD_CART_LOW_STOCK_ERROR);
            }
            //通过商品单价*商品数量=商品总价
            BigDecimal multiply = pmsSkuDto.getPrice().multiply(BigDecimal.valueOf(skuInfo.getSkuNum()));
            //相加 得到总价格
            totalMoney = totalMoney.add(multiply);
            //把循环出来的每一个skuDto信息 存放到集合中
            productList.add(new OmsCartDto(pmsSkuDto, skuInfo.getSkuNum(), userId));
        }

        //添加商品应付金额 totalMoney
        preSubmitDto.setTotalMoney(totalMoney);
        //添加商品邮费 freight     默认邮费10元
        preSubmitDto.setFreight(freight);
        //添加实际金额 totalMoney
        preSubmitDto.setPayMoney(totalMoney);
        //添加通过skuID获取的的sku商品的信息集合
        preSubmitDto.setProductList(productList);
        return preSubmitDto;
    }

    /**
     * 添加订单信息
     * ①创建一个订单对象 将订单的信息存进去 添加订单
     * ②通过skuId查询出来sku对象 添加到orderIeam订单详细表中  通过sku查询出来sku的总价格 然后更新到主订单
     * ③订单提交成功  通过skuId查询出来sku对象 进行库存减少
     * ④将订单orderId 传进rabbitMQ队列
     */
    @Override
    public OmsOrder addOmsOrder(PreSubmitParam preSubmitParam) {
        OmsOrder omsOrder = new OmsOrder();
        omsOrder.setUserId(preSubmitParam.getUserId());
        omsOrder.setOrderNo(OrderUtil.generateOrderNo());
        omsOrder.setPayType(Constants.Order.PayWay.ONLINE);
        omsOrder.setOrderStatus(Constants.Order.Status.OBLIGATION);
        omsOrder.setPayStatus(Constants.Order.PayStatus.WAIT);
        omsOrder.setExpirationTime(OrderUtil.generateOrderExpirationTime());
        omsOrder.setReceiverAddress(preSubmitParam.getReceiverAddress());
        omsOrder.setReceiverName(preSubmitParam.getReceiverName());
        omsOrder.setReceiverPhone(preSubmitParam.getReceiverPhone());
        //进行添加主订单 -->此时主订单的数量以及总金额等都为空
        int insert = omsOrderMapper.insert(omsOrder);
        if (insert > 0) {
            System.out.println("添加主订单成功");
        } else {
            System.out.println("添加主订单失败");
        }
        /**
         * 添加子订单   -->有几个sku商品 就添加几个子订单
         */
        BigDecimal totalMoney=new BigDecimal(0);//总价格
        BigDecimal payMoney=new BigDecimal(0);//需支付的价格
        int num=0;
        List<Long> skuId=new ArrayList<>();
        for (int i = 0; i < preSubmitParam.getSkuInfos().length; i++) {
            //获取到每个skuInfo对像
            SkuInfos skuInfo = preSubmitParam.getSkuInfos()[i];
            num+=skuInfo.getSkuNum();
            OmsOrderItem omsOrderItem=new OmsOrderItem();
            omsOrderItem.setOrderId(omsOrder.getId());
            //通过skuId获取到每个sku信息
            PmsSkuDto pmsSkuDto = pmsSkuMapper.pmsSkuDto(skuInfo.getSkuId());
            omsOrderItem.setSpuId(pmsSkuDto.getSpuId());
            omsOrderItem.setProductPic(pmsSkuDto.getPicUrl());
            omsOrderItem.setProductName(pmsSkuDto.getTitle());
            omsOrderItem.setProductPrice(pmsSkuDto.getPrice());
            omsOrderItem.setProductQuantity(skuInfo.getSkuNum());
            omsOrderItem.setSkuId(pmsSkuDto.getId());
            omsOrderItem.setProductAttr(pmsSkuDto.getProductSkuSpecification());
            skuId.add(skuInfo.getSkuId());
            /**
             * 计算商品的总价格和实际支付的金额进行更新到主订单
             */
            //累加 总金额
            totalMoney=totalMoney.add(pmsSkuDto.getPrice().multiply(BigDecimal.valueOf(skuInfo.getSkuNum())));
            omsOrderItemMapper.insert(omsOrderItem);

            /**
             * sku库存减少 我们购买的数量
             */
           int row= pmsSkuMapper.updateStock(skuInfo.getSkuNum(),skuInfo.getSkuId());
           if (row==0){
               logger.error("扣减商品sku库存失败");
               throw new BaseException(ResultEnum.REDUCE_INVENTORY_ERROR);
           }
        }
        //更新order订单的金额
        omsOrder.setTotalMoney(totalMoney);
        omsOrder.setPayMoney(totalMoney);
        //将商品的个数传进去
        omsOrder.setTotalNum(num);
        omsOrderMapper.updateById(omsOrder);
        System.out.println("收集的要删除的skuId为"+skuId);
        int count = pet_service_redisTemplate.remove(preSubmitParam.getUserId(),skuId);
        if(count == 0){
            logger.error("清空购物车失败！");
            throw new BaseException(ResultEnum.DELETE_CART_ERROR);
        }

        // 6. 订单超时处理
        sendMQMessage(omsOrder.getId().toString());
        /**
         * 发生消息到队列  -->订单超时处理
         */
        return  omsOrder;
    }

    private void sendMQMessage(String orderId) {
        //发送超时定时消息 (String exchange, String routingKey, Object message, MessagePostProcessor processor)
        rabbitTemplate.convertAndSend(OrderDelayQueueConfig.ORDER_EXCHANGE_NAME,
                OrderDelayQueueConfig.ORDER_DELAY_ROUTING_KEY, orderId, new MessagePostProcessor() {
                    @Override
                    public Message postProcessMessage(Message message) throws AmqpException {
                        //设置消息超时时间为10秒（测试）
                        message.getMessageProperties().setExpiration(Constants.Time.ORDER_OVER_TIME);
                        return message;
                    }
                });
}

    /**
     * 通过订单编号 查询到主订单的信息
     * @param orderNo
     * @return
     */
    @Override
    public OmsOrder getOrderByOderNo(String orderNo,Long userId){
        return omsOrderMapper.getOrderByOderNo(orderNo,userId);
    }

    /**
     * 通过用户id 查询用户的所有订单信息
     * @param id
     * @return
     */
    @Override
    public List<OmsOrder> getOrderByUserId(Long id) {
        return omsOrderMapper.getOrderByUserId(id);
    }

    @Override
    public boolean delOrder(String orderNo, Long id) {
        return omsOrderMapper.delOrder(orderNo,id);
    }


}
